package com.sky.service.impl;

import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkspaceService;
import com.sky.vo.*;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements ReportService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private WorkspaceService workspaceService;

    /**
     * 营业额统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public TurnoverReportVO turnoverReport(LocalDate begin, LocalDate end) {

        List<LocalDate> dateList = getLocalDates(begin, end);
        //存储每天营业总额的集合
        List<Double> turnoverList = new ArrayList<>();
        //循环获取每天营业总金额
        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            //查询当天00:00.00到23.59.59并且状态为已完成订单的营业总额
            Double sumAmount = orderMapper.getAmountByDateAndStatus(beginTime,endTime, Orders.COMPLETED);
            //添加入当天营业总额的集合中
            turnoverList.add(sumAmount == null ? 0.0 : sumAmount);
        }
        //日期
        String joinDate = StringUtils.join(dateList, ",");
        //金额
        String joinTurnover = StringUtils.join(turnoverList, ",");
        //返回对象
        TurnoverReportVO turnoverReportVO = new TurnoverReportVO();
        turnoverReportVO.setTurnoverList(joinTurnover);
        turnoverReportVO.setDateList(joinDate);
        return turnoverReportVO;
    }


    /**
     * 用户统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public UserReportVO userReport(LocalDate begin, LocalDate end) {
        //获取期间的每一天
        List<LocalDate> dateList = getLocalDates(begin, end);
        //新用户数量
        ArrayList<Integer> newUserList = new ArrayList<>();
        //所有用户数量
        ArrayList<Integer> totalUserList = new ArrayList<>();

        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);

            Integer newUserCount = userMapper.getCountByDate(beginTime,endTime);
            Integer totalUserCount = userMapper.getCountByDate(null, endTime);

            newUserList.add(newUserCount);
            totalUserList.add(totalUserCount);
        }
        UserReportVO userReportVO = new UserReportVO();
        //日期
        String joinDate = StringUtils.join(dateList, ",");
        //新客户
        String joinNewUser = StringUtils.join(newUserList, ",");
        //老客户
        String joinTotalUser = StringUtils.join(totalUserList, ",");

        userReportVO.setDateList(joinDate);
        userReportVO.setNewUserList(joinNewUser);
        userReportVO.setTotalUserList(joinTotalUser);

        return userReportVO;
    }

    /**
     * 订单统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public OrderReportVO orderReport(LocalDate begin, LocalDate end) {
        //获取期间的每一天
        List<LocalDate> dateList = getLocalDates(begin, end);
        //有效订单数量
        ArrayList<Integer> validOrderList = new ArrayList<>();
        //所有订单数量
        ArrayList<Integer> allOrderList = new ArrayList<>();

        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            //查询已完成订单-->有效订单
            Integer validOrder = orderMapper.getOrderCount(beginTime,endTime,Orders.COMPLETED);
            //查询全部订单--> 全部订单
            Integer orderCount = orderMapper.getOrderCount(beginTime, endTime, null);
            //存入有效订单集合
            validOrderList.add(validOrder);
            //存入全部订单集合
            allOrderList.add(orderCount);
        }
        OrderReportVO orderReportVO = new OrderReportVO();
        //日期
        String joinDate = StringUtils.join(dateList, ",");
        //有效订单数
        String joinValid = StringUtils.join(validOrderList, ",");
        //全部订单数
        String joinAll = StringUtils.join(allOrderList, ",");
        orderReportVO.setDateList(joinDate);    //日期
        orderReportVO.setValidOrderCountList(joinValid);    //每日有效订单数
        orderReportVO.setOrderCountList(joinAll);   //每日订单数
        //所有订单数
        Integer allOrder = allOrderList.stream().reduce(Integer::sum).get();
        //有效订单数
        Integer validOrder = validOrderList.stream().reduce(Integer::sum).get();
        //订单完成率
        Double completionRate = 0.0;
        if(allOrder != 0){
           completionRate =  validOrder.doubleValue() / allOrder;
        }
        orderReportVO.setTotalOrderCount(allOrder);     //订单总数
        orderReportVO.setValidOrderCount(validOrder);     //有效订单总数
        orderReportVO.setOrderCompletionRate(completionRate); //订单完成率
        return orderReportVO;
    }

    /**
     * 销量排名
     * @param begin
     * @param end
     * @return
     */
    @Override
    public SalesTop10ReportVO alesTop10Report(LocalDate begin, LocalDate end) {
        //开始时间
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        //结束时间
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
        //查询数据库获取数据
        List<GoodsSalesDTO> list = orderMapper.getTop10(beginTime,endTime,Orders.COMPLETED);
        //取数据中的name做一个新的集合
        List<String> nameList = list.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());
        //取数据中的number做一个新的集合
        List<Integer> numberList = list.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());
        //逗号(",")拼接
        String joinName = StringUtils.join(nameList, ",");
        String joinNumber = StringUtils.join(numberList, ",");

        SalesTop10ReportVO salesTop10ReportVO = new SalesTop10ReportVO();
        //菜品或套餐名称
        salesTop10ReportVO.setNameList(joinName);
        //销量
        salesTop10ReportVO.setNumberList(joinNumber);

        return salesTop10ReportVO;
    }

    @Override
    public void exportBusinessData(HttpServletResponse response) {
        //1.查询数据:近30天的数据
        //开始时间
        LocalDate begin = LocalDate.now().minusDays(30);
        //结束时间
        LocalDate end = LocalDate.now().minusDays(1);
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
        BusinessDataVO businessData = workspaceService.getBusinessData(beginTime, endTime);
        //加载的是target文件夹下的内容
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        try {
            //将input转化为Excel
            XSSFWorkbook excel = new XSSFWorkbook(inputStream);
            //先取sheet页
            XSSFSheet sheet = excel.getSheet("Sheet1");
            //取行和列
            sheet.getRow(1).getCell(1).setCellValue("时间:" + begin + "至" + end);
            sheet.getRow(3).getCell(2).setCellValue(businessData.getTurnover());
            sheet.getRow(3).getCell(4).setCellValue(businessData.getOrderCompletionRate());
            sheet.getRow(3).getCell(6).setCellValue(businessData.getNewUsers());
            sheet.getRow(4).getCell(2).setCellValue(businessData.getValidOrderCount());
            sheet.getRow(4).getCell(4).setCellValue(businessData.getUnitPrice());

            for (int i = 0; i < 30; i++) {
                //取第一天开始计算
                //天数需要每次加1
                begin = begin.plusDays(1);
                //开始时间
                LocalDateTime currentBeginTime = LocalDateTime.of(begin, LocalTime.MIN);
                //结束时间
                LocalDateTime currentEndTime = LocalDateTime.of(begin, LocalTime.MAX);
                //传递日期,查询数据
                BusinessDataVO businessData1 = workspaceService.getBusinessData(currentBeginTime, currentEndTime);
                //写入到excel里
                XSSFRow row = sheet.getRow(7+i);
                row.getCell(1).setCellValue(begin.toString());
                row.getCell(2).setCellValue(businessData1.getTurnover());
                row.getCell(3).setCellValue(businessData1.getValidOrderCount());
                row.getCell(4).setCellValue(businessData1.getOrderCompletionRate());
                row.getCell(5).setCellValue(businessData1.getUnitPrice());
                row.getCell(6).setCellValue(businessData1.getNewUsers());
            }

            //把文件导出,让浏览器下载
            ServletOutputStream outputStream = response.getOutputStream();
            excel.write(outputStream);

            //关闭资源
            outputStream.flush();
            outputStream.close();
            excel.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //获取时间区间内的每一天
    private List<LocalDate> getLocalDates(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);
        while (!begin.equals(end)){
            begin = begin.plusDays(1);
            dateList.add(begin);
        }
        return dateList;
    }
}
